package edu.del.teamknowledgebase.common.interceptor;

import edu.del.teamknowledgebase.common.constant.cache.SessionConstant;
import edu.del.teamknowledgebase.common.repository.RedisHttpSessionRepository;
import edu.del.teamknowledgebase.common.session.SessionData;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

/**
 * 认证拦截器
 * 拦截需要登录的接口，检查 Session 是否有效
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class AuthInterceptor implements HandlerInterceptor {

    private final RedisHttpSessionRepository redisHttpSessionRepository;

    @Override
    public boolean preHandle(HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler) throws Exception {
        // 跨域请求
        if ("OPTIONS".equals(request.getMethod())) {
            return true;
        }

        // 获取 HttpSession（不创建新的）
        // Spring Session 会自动从 Redis 恢复 Session（如果存在）
        HttpSession session = request.getSession(false);

        // 如果没有 SessionID，返回未登录
        if (session == null) {
            log.warn("未登录访问：path={}, ip={}", request.getRequestURI(), getClientIp(request));
            sendUnauthorizedResponse(response, "未登录");
            return false;
        }

        // 从 Session 中获取用户信息
        SessionData sessionData = (SessionData) session.getAttribute(SessionConstant.USER_INFO_KEY);

        if (sessionData == null) {
            log.warn("Session 中无用户信息：sessionId={}, path={}", session.getId(), request.getRequestURI());
            sendUnauthorizedResponse(response, "登录已过期");
            return false;
        }

        // 将用户信息存入 request attribute，供后续使用
        request.setAttribute("sessionData", sessionData);
        request.setAttribute("userId", sessionData.getUserId());
        request.setAttribute("username", sessionData.getUsername());
        request.setAttribute("role", sessionData.getRole());

        log.debug("认证通过：userId={}, username={}, sessionId={}",
                sessionData.getUserId(), sessionData.getUsername(), session.getId());

        return true;
    }

    /**
     * 发送未授权响应
     */
    private void sendUnauthorizedResponse(HttpServletResponse response, @NonNull String message) throws Exception {
        response.setStatus(401);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(String.format("{\"code\":401,\"message\":\"%s\",\"success\":false}", message));
    }

    /**
     * 获取客户端 IP
     */
    private String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}
